package com.tuhao.www.dao;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.tuhao.www.util.GenericsUtils;
import com.tuhao.www.util.Page;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

/**
 * mybatis的baseDao层
 */
@Repository("baseDao")  
public class BaseDao<T, PK extends Serializable> extends SqlSessionDaoSupport implements Serializable {  
      
	private static final long serialVersionUID = -5972137473505999808L;

	private final String POSTFIX = "Dao";  
  
    private final String _INSERT = ".insert";  
  
    private final String _INSERTSELECTIVE = ".insertSelective";  
  
    private final String _SELECTBYPRIMARYKEY = ".selectByPrimaryKey";  
  
    private final String _UPDATEBYPRIMARYKEY = ".updateByPrimaryKey";  
  
    private final String _UPDATEBYPRIMARYKEYSELECTIVE = ".updateByPrimaryKeySelective";
    
    private final String _UPDATEBYPRIMARYKEYSELECTIVEMAP = ".updateByPrimaryKeySelectiveMap";  
  
    private final String _DELETEBYPRIMARYKEY = ".deleteByPrimaryKey";  
      
    @Autowired
    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {  
        super.setSqlSessionFactory(sqlSessionFactory);  
    } 
    
    /*GenericsUtils为工具类，请见下方代码 
          泛型获得XXX变成XXXDao，对应Mapper.xml中的namespace命名 
        */  
    @SuppressWarnings({ "unchecked", "rawtypes" })  
    public String getNampSpace() {  
        Class<T> clazz = (Class) GenericsUtils.getSuperClassGenricType(this.getClass());
        String simpleName = clazz.getSimpleName() + POSTFIX;  
        return simpleName;  
    }  
    
    /**
     * 添加数据-实体全属性
     * @param entity
     * @return
     */
    public int insert(T entity) {  
        return getSqlSession().insert(this.getNampSpace() + _INSERT, entity);  
    }
    
    /**
     * 添加数据
     * @param entity
     * @return
     */
    public int insert(String nameSpace, T entity) {  
        return getSqlSession().insert(nameSpace, entity);  
    }
      
    /**
     * 添加数据-实体可选属性
     * @param record
     * @return
     */  
    public int insertSelective(T record) {  
        return getSqlSession().insert(this.getNampSpace() + _INSERTSELECTIVE, record);  
    }  
  
    /**
     * 查询某个实体
     * @param id
     * @return
     */
    public T selectByPrimaryKey(PK id) {  
        return getSqlSession().selectOne(this.getNampSpace() + _SELECTBYPRIMARYKEY, id);  
    }  
  
    /**
     * 更新某个实体-全属性  
     * @param record
     * @return
     */
    public int updateByPrimaryKey(T record) {  
        return getSqlSession().update( this.getNampSpace() + _UPDATEBYPRIMARYKEY, record);  
    }  
  
    /**
     * 更新某个实体-可选属性
     * @param record
     * @return
     */
    public int updateByPrimaryKeySelective(T record) {  
        return getSqlSession().update(this.getNampSpace() + _UPDATEBYPRIMARYKEYSELECTIVE, record);  
    }  
    
    /**
     * 更新某个实体-可选属性--map
     * @param param
     * @return
     */
    public int updateByPrimaryKeySelective(Map<String, Object> param) {  
        return getSqlSession().update(this.getNampSpace() + _UPDATEBYPRIMARYKEYSELECTIVEMAP, param);  
    }
    
    /**
     * 删除某个实体
     * @param id
     * @return
     */
    public int deleteByPrimaryKey(PK id) {  
        return getSqlSession().delete(this.getNampSpace() + _DELETEBYPRIMARYKEY, id);  
    } 
    
    /**
     * 删除实体
     * @return
     */
    public int delete(String nampSpace, Map<String, Object> param) {  
        return getSqlSession().delete(nampSpace, param);  
    }  
  
    /**
     * 实体查询-分页/不分页
     * @param statementKey
     * @param page
     * @param parameter
     * @param isSimplePage
     * @return
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })  
    public PageInfo pageFind(String statementKey, Page page, Object parameter,
                             Boolean isSimplePage) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        Map params = new HashMap();  
        if (parameter != null) {  
            if (parameter instanceof Map) {  
                params.putAll((Map) parameter);  
            } else {  
                Map parameterObject = PropertyUtils.describe(parameter);  
                params.putAll(parameterObject);  
            }  
        }  
        PageHelper.startPage(page.getCurrentPage(), page.getPernum(), isSimplePage);  
        List<T> list = getSqlSession().selectList(statementKey, params);  
        PageInfo pageInfo = new PageInfo(list);  
  
        return pageInfo;  
    }
    
    /**
     * 实体查询-分页/不分页
     * @param statementKey
     * @param page
     * @param parameter
     * @param isSimplePage
     * @return
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })  
    public <M> PageInfo pageFindModel(String statementKey, Page page, Object parameter,  
            Boolean isSimplePage) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {  
        Map params = new HashMap();  
        if (parameter != null) {  
            if (parameter instanceof Map) {  
                params.putAll((Map) parameter);  
            } else {  
                Map parameterObject = PropertyUtils.describe(parameter);  
                params.putAll(parameterObject);  
            }  
        }  
        PageHelper.startPage(page.getCurrentPage(), page.getPernum(), isSimplePage);
        List<M> list = getSqlSession().selectList(statementKey, params);  
        PageInfo pageInfo = new PageInfo(list);
        return pageInfo;  
    }
  
    /**
     * 实体查询-前几条
     * @param top
     * @param statementKey
     * @param parameter
     * @return
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })  
    public List<T> findTop(int top, String statementKey, Object parameter) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {  
        Map params = new HashMap();  
        if (parameter != null) {  
            if (parameter instanceof Map) {  
                params.putAll((Map) parameter);  
            } else {  
                Map parameterObject = PropertyUtils.describe(parameter);  
                params.putAll(parameterObject);  
            }  
        }  
        List<T> list = getSqlSession().selectList(statementKey, params, new RowBounds(0, top));  
        return list;  
    }  
  
    /**
     * 实体查询-第一条
     * @param statementKey
     * @param parameter
     * @return
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     */
    public T findTopOne(String statementKey, Object parameter) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {  
        List<T> list = findTop(1, statementKey, parameter);  
        return CollectionUtils.isEmpty(list) ? null : list.get(0);  
    }  
    
    /**
     * 实体查询-分页
     * @param statementKey
     * @param page
     * @param parameter
     * @return
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })  
    public <M> PageInfo pageFindModel(String statementKey, Page page, Object parameter) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {  
        Map params = new HashMap();  
        if (parameter != null) {  
            if (parameter instanceof Map) {  
                params.putAll((Map) parameter);  
            } else {  
                Map parameterObject = PropertyUtils.describe(parameter);  
                params.putAll(parameterObject);  
            }  
        }  
        PageHelper.startPage(page.getCurrentPage(), page.getPernum());  
        List<M> list = getSqlSession().selectList(statementKey, params);  
        PageInfo pageInfo = new PageInfo(list);  
  
        return pageInfo;  
    }
    
    /**
     * 实体查询-所有
     * @param statementKey：表示查询语句在mapping中的对于的id名称
     * @param param：参数
     * @return ：返回一个list
     * @throws IllegalAccessException :每个都会抛出此异常
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     */
    @SuppressWarnings({ "rawtypes", "unchecked" }) 
	public List<T> selectList(String statementKey, Map<String,Object> param) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		 Map params = new HashMap();  
        if (param != null) {  
            if (param instanceof Map) {  
                params.putAll((Map) param);  
            } else {  
                Map parameterObject = PropertyUtils.describe(param);  
                params.putAll(parameterObject);
            }  
        }
        List<T> list = getSqlSession().selectList(statementKey,params);
		return list;
	}
}